﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using IdentityModel;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Stee.CAP8.ACL;

namespace SampleAPIServiceForGlobal.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class TestAuthenticateController : ControllerBase
    {
        private readonly ILogger<TestAuthenticateController> _logger;
        private UserStore _store;

        public TestAuthenticateController(ILogger<TestAuthenticateController> logger, UserStore store)
        {
            _logger = logger;
            _store = store;
        }
 
        [ACLContract(true)]
        [HttpPost("SignIn")]
        public IActionResult Authenticate([FromBody]UserDto userDto)
        {
            var user = _store.FindUser(userDto.UserName, userDto.Password);
            if (user == null) return Unauthorized();

            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes("TestAuthenticate~#$%#%^2235");
            var authTime = DateTime.UtcNow;
            var expiresAt = authTime.AddDays(7);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(JwtClaimTypes.Audience,"api"),
                    new Claim(JwtClaimTypes.Issuer,"ACE&ST"),
                    new Claim(JwtClaimTypes.Id, user.Id.ToString()),
                    new Claim(JwtClaimTypes.Name, user.Name),
                    new Claim("rolecode", user.Role),
                    new Claim(JwtClaimTypes.Email, user.Email),
                    new Claim(JwtClaimTypes.PhoneNumber, user.PhoneNumber)
                }),
                Expires = expiresAt,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);
            return Ok(new
            {
                access_token = tokenString,
                token_type = "Bearer",
                profile = new
                {
                    sid = user.Id,
                    name = user.Name,
                    auth_time = new DateTimeOffset(authTime).ToUnixTimeSeconds(),
                    expires_at = new DateTimeOffset(expiresAt).ToUnixTimeSeconds()
                }
            });
        }
       
        [ACLContract("TestTask1")]
        [HttpGet]
        public IEnumerable<User> Get()
        {
            return _store.Users;
        }


        [ACLContract(false, "TestTask2", "TestTask9")]
        [HttpGet("{id}")]
        public User Get(int id)
        {
            return _store.Users.Where(q => q.Id == id).FirstOrDefault();
        }

        [ACLContract(true, "TestTask2", "TestTask9")]
        [HttpPost("AddUser")]
        public void Post([FromBody] User value)
        {
            _store.Users.Add(value);
        }

        [ACLContract(false ,"TestTask1", "TestTask2", "TestTask3")]
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] User user)
        {
            var userOld = _store.Users.Where(q => q.Id == id).FirstOrDefault();
            userOld.Name = user.Name;
            userOld.Password = user.Password;
        }

        [ACLContract(true, "TestTask1", "TestTask22", "TestTask3")]
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
            var user = _store.Users.Where(q => q.Id == id).FirstOrDefault();
            _store.Users.Remove(user);
        }
    }
}
